package com.bcgtgjyb.huanwen.customview.mylibrary;

import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Arc;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;

/**
 * Created by huanwen on 2015/9/1.
 */
public class TaiJiButton extends Component implements Component.DrawTask {
    private float rolate = 360;
    private Paint mGrayPaint;
    private Paint mBlackPaint;
    private RectFloat backRectF;
    private RectFloat rectF;
    private RectFloat rectF2;
    private boolean isInit = false;
    private boolean isStopFinish = false;
    private int stopCount = 0;
    private boolean isLine = true;
    private boolean isLoading = false;
    private int colorBlack = Color.BLACK.getValue();
    private int colorGray = Color.GRAY.getValue();
    private float mR = 0;
    private float raduisX1 = 0;
    private float raduisY1 = 0;
    private float raduisX2 = 0;
    private float raduisY2 = 0;
    private int velocity = 1000;
    private AnimatorValue rotateAnimator = null;
    private AnimatorValue lineArcAnimator = null;
    private float rotateRatio = 0f;
    private float lineArcRatio = 0f;
    private EventHandler eventHandler = new EventHandler(EventRunner.getMainEventRunner());

    /**
     * 构造
     *
     * @param context 上下文
     * @param attrSet 属性集
     */
    public TaiJiButton(Context context, AttrSet attrSet) {
        super(context, attrSet);
        addDrawTask(this);

        mGrayPaint = new Paint();
        mBlackPaint = new Paint();
        backRectF = new RectFloat();
        rectF = new RectFloat();
        rectF2 = new RectFloat();
    }

    private void loading() {
        if (rotateAnimator == null) {
            loadAnimator();
        } else {
            rotateAnimator.start();
        }
        eventHandler.postTask(new Runnable() {
            @Override
            public void run() {
                if (isStopFinish) {
                    if (stopCount > 3) {
                        return;
                    } else {
                        stopCount++;
                    }
                }
                loading();
            }
        }, 10);
    }

    private void loadAnimator() {
        rotateAnimator = new AnimatorValue();
        rotateAnimator.setDuration(velocity);
        rotateAnimator.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float v) {
                rotateRatio = v;
                invalidate();
            }
        });
        rotateAnimator.start();
        invalidate();
    }

    public boolean isLoading() {
        return isLoading;
    }

    /**
     * set the animation start
     */
    public void startLoad() {
        isLoading = true;
        isStopFinish = false;
        stopCount = 0;
        setLineArcAnimator(true);
        loading();
    }

    /**
     * set the animation stop
     */
    public void stopLoad() {
        isLoading = false;
        setLineArcAnimator(false);
    }

    private void setLineArcAnimator(boolean isLine2arc) {
        isLine = isLine2arc;
        if (lineArcAnimator == null) {
            lineArcAnimator = new AnimatorValue();
            lineArcAnimator.setDuration(velocity);
            lineArcAnimator.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
                @Override
                public void onUpdate(AnimatorValue animatorValue, float value) {
                    if (isLine) {
                        lineArcRatio = value;
                    } else {
                        lineArcRatio = 1.0f - value;
                        if (lineArcRatio < 0.001f) {
                            isStopFinish = true;
                        }
                    }
                    invalidate();
                }
            });
            lineArcAnimator.start();
        } else {
            lineArcAnimator.stop();
            lineArcAnimator.start();
        }
        invalidate();
    }

    @Override
    public void onDraw(Component component, final Canvas canvas) {
        // 初始化
        if (!isInit) {
            mGrayPaint.setColor(new Color(colorGray));
            mBlackPaint.setColor(new Color(colorBlack));
            mR = ((float) getWidth()) / 2;
            raduisX1 = ((float) getWidth()) / 2 + mR / 2;
            raduisY1 = ((float) getWidth()) / 2;
            raduisX2 = ((float) getWidth()) / 2 - mR / 2;
            raduisY2 = ((float) getWidth()) / 2;
            isInit = true;
        }

        // 旋转刷新
        if (rotateAnimator != null && rotateAnimator.isRunning()) {
            canvas.rotate(rolate * rotateRatio, ((float) getWidth()) / 2, ((float) getWidth()) / 2);
            invalidate();
        }

        // 画出背景半圆
        backRectF.fuse(0, 0, getWidth() - lineArcRatio * getWidth(), getHeight() - lineArcRatio * getHeight());
        Arc arc1 = new Arc();
        arc1.setArc(0, 180, true);
        Arc arc2 = new Arc();
        arc2.setArc(180, 180, true);
        canvas.drawArc(backRectF, arc1, mGrayPaint);
        canvas.drawArc(backRectF, arc2, mBlackPaint);

        // 椭圆渐变
        rectF.modify(((float) getWidth()) / 2 - mR, ((float) getWidth()) / 2 - lineArcRatio * mR / 2,
                ((float) getWidth()) / 2, ((float) getWidth()) / 2 + lineArcRatio * mR / 2);
        rectF2.modify(((float) getWidth()) / 2, ((float) getWidth()) / 2 - lineArcRatio * mR / 2,
                ((float) getWidth()) / 2 + mR, ((float) getWidth()) / 2 + lineArcRatio * mR / 2);
        canvas.drawArc(rectF, arc2, mGrayPaint);
        canvas.drawArc(rectF2, arc1, mBlackPaint);
        if (lineArcAnimator != null && lineArcAnimator.isRunning()) {
            invalidate();
        }

        // 圆心放大
        canvas.drawCircle(raduisX1, raduisY1, lineArcRatio * mR / 5, mGrayPaint);
        canvas.drawCircle(raduisX2, raduisY2, lineArcRatio * mR / 5, mBlackPaint);
    }
}
